/*******************************************************************************
*  file    : interfaces.hpp
*  created : 07.07.2012
*  author  : Slyshyk Oleksiy (alex312@meta.ua)
*******************************************************************************/

#ifndef INTERFACES_HPP
#define INTERFACES_HPP

#include <QDebug>
#include <QtPlugin>
#include <QVector>
#include <QVariant>
#include <complex>
#include <vector>

#include <stdint.h>

QT_BEGIN_NAMESPACE
class QImage;
class QWidget;
class QString;
class QStringList;
QT_END_NAMESPACE


struct NamedData
{
    double                             sampleRate;
    QString                            name;
    std::vector<std::complex<double> > data;
    QVariantMap                        pantry;
};

struct NamedIntData
{
    uint32_t              sampleRate;
    QString               name;
    QVariantMap           pantry;
    std::vector<int32_t>  data;

    operator NamedData()
    {
        NamedData res;
        res.sampleRate = sampleRate;
        res.name       = name;
        res.pantry     = pantry;
        res.data.resize(data.size());
        for(decltype(data.size()) i = 0; i < data.size(); ++i )
            res.data[i] = data.at(i);

        return res;
    }

    NamedIntData() : sampleRate()  {}
    NamedIntData(const NamedData& nd)
    {
        sampleRate = nd.sampleRate;
        name       = nd.name;
        pantry     = nd.pantry;
        data.resize(nd.data.size());
        for(decltype(data.size()) i = 0; i < data.size(); ++i )
            {
                data[i] = static_cast<int32_t>(nd.data.at(i).real());
            }
    }
    NamedIntData(const NamedData* nd)
    {
        if(nd)
            {
                sampleRate = nd->sampleRate;
                name       = nd->name;
                pantry     = nd->pantry;
                data.resize(nd->data.size());
                for(decltype(data.size()) i = 0; i < data.size(); ++i )
                    {
                        data[i] = static_cast<int32_t>(nd->data.at(i).real());
                    }
            }
    }
};

class DataInterface
{
public:
    virtual ~DataInterface() {}

    virtual QString                        name() const = 0;
    virtual double                         sampleRate() const = 0;
    virtual QVector<std::complex<double> > getData() = 0;
};

class ReadFileFormatInterface
{
public:
    virtual                                ~ReadFileFormatInterface(){}
    virtual QString                        name() const = 0;
    virtual void                           setName(const QString&) = 0;
    virtual QStringList                    formats() const = 0;
    virtual QString                        fileFilter() const = 0;
    virtual bool                           read() = 0;
    virtual bool                           read(const QString&) = 0;
    virtual double                         sampleRate() const = 0;
    virtual QVector<std::complex<double> > getData() = 0;
    virtual void                           flush() = 0;
};

class SaveFileFormatInterface
{
public:
    virtual ~SaveFileFormatInterface(){}
    virtual QString name() const = 0;
    virtual bool    saveDataToFile(const QString& fileName, const NamedData& data) = 0;
    virtual QString error() = 0;
};

class SaveLoadObjectInterface
{
public:
    virtual ~SaveLoadObjectInterface(){}
    virtual QString     name() const = 0;
    virtual QString     error() const = 0;
    virtual QStringList formats() const = 0;
    virtual QString     fileFilter() const = 0;
    virtual bool        saveObjectToFile(const QString& fileName, QObject* object) = 0;
    virtual QObject*    loadObjectFromFile(const QString& fileName) = 0;
};


class TransformNamedData
{
public:
    ~TransformNamedData() {}
    virtual QString     name       ( ) const                 = 0;
    virtual QStringList patternList( ) const                 = 0;
    virtual NamedData*  transform  ( const NamedData* data, const QVariant& params)  = 0;
};

class TransformNamedIntData
{
public:
    ~TransformNamedIntData() {}
    virtual QString        name       ( ) const                 = 0;
    virtual QStringList    patternList( ) const                 = 0;
    virtual NamedIntData*  transform  ( const NamedIntData* data, const QVariant& params)  = 0;
};



#define DataInterface_iid "tmx.com.ua.dsp.lab.DataInterface"
Q_DECLARE_INTERFACE(DataInterface, DataInterface_iid)

#define ReadFileFormatInterface_iid "tmx.com.ua.dsp.lab.ReadFileFormatInterface"
Q_DECLARE_INTERFACE(ReadFileFormatInterface, ReadFileFormatInterface_iid)

#define SaveFileFormatInterface_iid "tmx.com.ua.dsp.lab.SaveFileFormatInterface"
Q_DECLARE_INTERFACE(SaveFileFormatInterface, SaveFileFormatInterface_iid)

#define TransformNamedData_iid "tmx.com.ua.dsp.lab.TransformNamedData"
Q_DECLARE_INTERFACE(TransformNamedData, TransformNamedData_iid)
#define TransformNamedIntData_iid "tmx.com.ua.dsp.lab.TransformNamedIntData"
Q_DECLARE_INTERFACE(TransformNamedIntData, TransformNamedIntData_iid)

#define SaveLoadObjectInterface_iid "tmx.com.ua.dsp.lab.SaveLoadObjectInterface"
Q_DECLARE_INTERFACE(SaveLoadObjectInterface, SaveLoadObjectInterface_iid)

#endif // INTERFACES_HPP
